<?php
header("Access-Control-Allow-Origin:*");
header('Access-Control-Allow-Headers:x-requested-with, content-type');

const g_FileName = "data.raw";
const g_MaxBackupNum = 5;

function finish($code, $data = null, $msg = null) {
    $result = array();
    if (!is_null($code)) $result['code'] = $code;
    if (!is_null($data)) $result['data'] = $data;
    if (!is_null($msg)) $result['msg'] = $msg;
    exit(json_encode($result));
}

function read() {
    if (file_exists(g_FileName))
        return file_get_contents(g_FileName);
    else
        return "[]";
}

function write($text) {
    $file = fopen(g_FileName, 'w');
    if (empty($file))
        finish(200, null, "文件写入失败");
    fwrite($file, $text);
    fclose($file);
}

function saveBackup() {
    if (!file_exists(g_FileName)) return;
    $backupFiles = glob('./data_backup_*.raw');
    if (count($backupFiles) >= g_MaxBackupNum) {
        sort($backupFiles);
        unlink($backupFiles[0]);
    }
    $timestamp = date("Y-m-d_h-i-s", time());
    $fileName = "data_backup_" . $timestamp . ".raw";
    copy(g_FileName, $fileName);
}

function sortEntry($a, $b){
    return $b['time'] - $a['time'];
}
// 检查线上版本和新版本冲突
// 理论上，线上版本如果包含新版本没有的条目，说明有其他地方上传的新条目进来
// 但是有例外，如果本地删除了许多条目，再上传，这些条目只能是旧条目
function checkConflict($newData, $remoteData) {
    usort($newData, "sortEntry");
    usort($remoteData, "sortEntry");
    // 遍历旧条目
    foreach($remoteData as $remoteEntry) {
        $foundMatch = false;
        foreach($newData as $newEntry) {
            if ($remoteEntry['time'] == $newEntry['time']) {
                $foundMatch = true;
                if ($remoteEntry['content'] != $newEntry['content'])
                    return true;
                break;
            }
        }
        if (!$foundMatch) {
            return true;
        }
    }
    return false;
}

$postData = file_get_contents('php://input');
$requests = !empty($postData) ? json_decode($postData, true) : array();

$pAction = $requests['action'];
$pData = $requests['data'];
$pForce = $requests['force'] == 'true' ? true : false;

if (empty($pAction)) {
    finish(200, null, "参数错误");
}

$version = json_decode(read(), true);

switch($pAction) {
    case "upload": {
        $newVersion = array("time" => time(), "data" => $pData);
        if (!$pForce && checkConflict($pData, $version['data'])) {
            finish(101, "冲突，请先下载新版本合并后再上传");
        }
        saveBackup();
        write(json_encode($newVersion));
        finish(100);
        break;
    }
    case "download": {
        if (empty($version))
            finish(200, null, "文件读取失败");
        finish(100, $version['data']);
        break;
    }
}
?>